"""
670. 最大交换 - 测试数据生成器

用于生成各种类型的测试数据，验证算法的正确性和性能
"""

import random
from typing import List, Tuple

class TestDataGenerator:
    """测试数据生成器"""
    
    def __init__(self, seed: int = 42):
        """初始化随机种子以确保可重现性"""
        random.seed(seed)
    
    def generate_basic_cases(self) -> List[Tuple[str, int]]:
        """生成基本测试用例"""
        return [
            ("示例1", 2736),
            ("示例2", 9973),
            ("单个数字", 5),
            ("两位数递增", 12),
            ("两位数递减", 21),
            ("三位数", 123),
            ("包含0", 1000),
        ]
    
    def generate_boundary_cases(self) -> List[Tuple[str, int]]:
        """生成边界测试用例"""
        return [
            ("最小值", 0),
            ("单位数", 9),
            ("两位数最小", 10),
            ("两位数最大", 99),
            ("三位数最小", 100),
            ("四位数", 1234),
            ("五位数", 12345),
            ("大数值", 98765432),
            ("最大值", 99999999),  # 接近10^8
        ]
    
    def generate_pattern_cases(self) -> List[Tuple[str, int]]:
        """生成特定模式的测试用例"""
        return [
            ("严格递增", 123456),
            ("严格递减", 654321),
            ("全相同", 777777),
            ("部分相同", 112233),
            ("对称数", 123321),
            ("回文数", 12321),
            ("最大数在前", 987654),
            ("最大数在后", 123459),
            ("最大数在中", 124953),
        ]
    
    def generate_special_cases(self) -> List[Tuple[str, int]]:
        """生成特殊情况的测试用例"""
        return [
            ("重复数字1", 1993),
            ("重复数字2", 1223),
            ("多个相同最大值", 4994),
            ("零在中间", 1032),
            ("零在末尾", 1230),
            ("交换后无变化", 9876),
            ("只需一次交换", 1349),
            ("最优交换在末尾", 1239),
        ]
    
    def generate_random_number(self, min_digits: int = 1, max_digits: int = 8) -> int:
        """生成指定位数范围的随机数"""
        num_digits = random.randint(min_digits, max_digits)
        
        if num_digits == 1:
            return random.randint(0, 9)
        
        # 确保第一位不为0
        first_digit = random.randint(1, 9)
        remaining_digits = [random.randint(0, 9) for _ in range(num_digits - 1)]
        
        number_str = str(first_digit) + ''.join(map(str, remaining_digits))
        return int(number_str)
    
    def generate_number_with_pattern(self, pattern: str) -> int:
        """根据指定模式生成数字"""
        if pattern == "ascending":
            # 生成递增序列
            digits = sorted([random.randint(1, 9) for _ in range(random.randint(3, 6))])
            return int(''.join(map(str, digits)))
        
        elif pattern == "descending":
            # 生成递减序列
            digits = sorted([random.randint(1, 9) for _ in range(random.randint(3, 6))], reverse=True)
            return int(''.join(map(str, digits)))
        
        elif pattern == "duplicate":
            # 生成包含重复数字的数
            length = random.randint(3, 6)
            digits = [random.randint(1, 9) for _ in range(length)]
            # 随机选择两个位置设为相同数字
            pos1, pos2 = random.sample(range(length), 2)
            digits[pos2] = digits[pos1]
            return int(''.join(map(str, digits)))
        
        elif pattern == "with_zero":
            # 生成包含0的数字
            length = random.randint(3, 6)
            digits = [random.randint(1, 9)]  # 第一位不为0
            digits.extend([random.randint(0, 9) for _ in range(length - 1)])
            # 确保至少有一个0
            if 0 not in digits:
                digits[random.randint(1, length - 1)] = 0
            return int(''.join(map(str, digits)))
        
        else:
            return self.generate_random_number()
    
    def generate_performance_cases(self) -> List[Tuple[str, int]]:
        """生成性能测试用例"""
        cases = []
        
        # 不同位数的随机数
        for digits in [1, 2, 3, 4, 5, 6, 7, 8]:
            for _ in range(3):  # 每个位数生成3个
                num = self.generate_random_number(digits, digits)
                cases.append((f"{digits}位随机数", num))
        
        # 特定模式的数字
        patterns = ["ascending", "descending", "duplicate", "with_zero"]
        for pattern in patterns:
            for _ in range(5):
                num = self.generate_number_with_pattern(pattern)
                cases.append((f"{pattern}模式", num))
        
        return cases
    
    def generate_all_test_cases(self) -> List[Tuple[str, int]]:
        """生成所有测试用例"""
        all_cases = []
        
        all_cases.extend(self.generate_basic_cases())
        all_cases.extend(self.generate_boundary_cases())
        all_cases.extend(self.generate_pattern_cases())
        all_cases.extend(self.generate_special_cases())
        all_cases.extend(self.generate_performance_cases())
        
        return all_cases
    
    def save_test_cases_to_file(self, filename: str = "test_cases.txt"):
        """将测试用例保存到文件"""
        cases = self.generate_all_test_cases()
        
        with open(filename, 'w', encoding='utf-8') as f:
            f.write("# 670. 最大交换 - 测试用例\n\n")
            
            for i, (name, num) in enumerate(cases, 1):
                f.write(f"## 测试用例 {i}: {name}\n")
                f.write(f"输入: {num}\n")
                f.write(f"位数: {len(str(num))}\n")
                f.write(f"数字序列: {' '.join(str(num))}\n\n")
        
        print(f"测试用例已保存到 {filename}")
        print(f"共生成 {len(cases)} 个测试用例")

def analyze_number_properties(num: int) -> dict:
    """分析数字的性质"""
    digits = list(str(num))
    n = len(digits)
    
    if n == 0:
        return {"length": 0}
    
    # 检查单调性
    is_ascending = all(digits[i] <= digits[i+1] for i in range(n-1))
    is_descending = all(digits[i] >= digits[i+1] for i in range(n-1))
    is_strictly_ascending = all(digits[i] < digits[i+1] for i in range(n-1))
    is_strictly_descending = all(digits[i] > digits[i+1] for i in range(n-1))
    
    # 统计数字频率
    digit_freq = {}
    for digit in digits:
        digit_freq[digit] = digit_freq.get(digit, 0) + 1
    
    # 找最大和最小数字
    max_digit = max(digits)
    min_digit = min(digits)
    
    # 检查是否有重复
    has_duplicates = any(freq > 1 for freq in digit_freq.values())
    
    # 检查是否包含0
    has_zero = '0' in digits
    
    return {
        "number": num,
        "length": n,
        "digits": digits,
        "is_ascending": is_ascending,
        "is_descending": is_descending,
        "is_strictly_ascending": is_strictly_ascending,
        "is_strictly_descending": is_strictly_descending,
        "max_digit": max_digit,
        "min_digit": min_digit,
        "digit_frequency": digit_freq,
        "has_duplicates": has_duplicates,
        "has_zero": has_zero,
        "unique_digits": len(digit_freq),
    }

def print_number_analysis(name: str, num: int):
    """打印数字分析结果"""
    props = analyze_number_properties(num)
    print(f"\n=== {name} ===")
    print(f"数字: {num}")
    print(f"位数: {props['length']}")
    print(f"数字序列: {' '.join(props['digits'])}")
    print(f"最大数字: {props['max_digit']}")
    print(f"最小数字: {props['min_digit']}")
    print(f"严格递增: {props['is_strictly_ascending']}")
    print(f"严格递减: {props['is_strictly_descending']}")
    print(f"有重复数字: {props['has_duplicates']}")
    print(f"包含0: {props['has_zero']}")
    print(f"不同数字个数: {props['unique_digits']}")
    print(f"数字频率: {props['digit_frequency']}")

def main():
    """主函数 - 生成并分析测试数据"""
    print("670. 最大交换 - 测试数据生成器")
    print("=" * 50)
    
    generator = TestDataGenerator()
    
    # 生成基本测试用例
    print("\n基本测试用例:")
    basic_cases = generator.generate_basic_cases()
    for name, num in basic_cases:
        print_number_analysis(name, num)
    
    # 生成边界测试用例
    print("\n边界测试用例:")
    boundary_cases = generator.generate_boundary_cases()
    for name, num in boundary_cases:
        print_number_analysis(name, num)
    
    # 生成特殊测试用例
    print("\n特殊测试用例:")
    special_cases = generator.generate_special_cases()
    for name, num in special_cases:
        print_number_analysis(name, num)
    
    # 保存所有测试用例到文件
    generator.save_test_cases_to_file()
    
    # 生成一些随机测试用例进行快速验证
    print("\n随机测试用例示例:")
    for i in range(5):
        num = generator.generate_random_number(3, 6)
        print_number_analysis(f"随机用例{i+1}", num)

if __name__ == "__main__":
    main()
